//
//  ZZCRefreshControl.swift
//  weibo
//
//  Created by zhangzuchao on 2017/4/1.
//  Copyright © 2017年 zhangZuChao. All rights reserved.
//

import UIKit

//  自定义控件的高度
private let ZZCRefreshControlHeight: CGFloat = 50

//  自定义下拉刷新的状态
enum ZZCRefreshControlType {
    //  下拉刷新
    case normal
    //  松手就刷新
    case pulling
    //  正在刷新
    case refreshing
}

class ZZCRefreshControl: UIControl {
 
    //  默认是下拉刷新的状态
    var refreshType: ZZCRefreshControlType = .normal{
        didSet {
            switch refreshType {
            case .normal:
                print("下拉刷新")
                
                //  1.箭头显示,箭头重置,关闭风火轮,文字改成下拉刷新
                pullDownImageView.isHidden = false
                indicatorView.stopAnimating()
                messageLabel.text = "下拉刷新"
                UIView.animate(withDuration: 0.25, animations: {
                    
                    //  箭头重置
                    self.pullDownImageView.transform = CGAffineTransform.identity
                })
                
                //  只有上一次状态是正在刷新才让其重置, oldValue表示你上一次保存的值
                if oldValue == .refreshing {
                    UIView.animate(withDuration: 0.25, animations: {
                        //  重置原始的显示内容
                        self.currentScrollView?.contentInset.top -= ZZCRefreshControlHeight
                    })
                }
                
                
            case .pulling:
                print("松手就刷新")
                
                //  箭头调转,文字改成松手就刷新
                UIView.animate(withDuration: 0.25, animations: {
                    self.pullDownImageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
                })
                messageLabel.text = "松手就刷新"
                
            case .refreshing:
                print("正在刷新")
                
                //  1. 箭头隐藏, 开启风火轮, 文字改成正在刷新
                pullDownImageView.isHidden = true
                indicatorView.startAnimating()
                messageLabel.text = "正在刷新..."
                UIView.animate(withDuration: 0.25, animations: {
                    
                    //  设置停留,把内容区域变大
                    self.currentScrollView?.contentInset.top += ZZCRefreshControlHeight
                }, completion: { (_) in
                    
                    //  通知外面刷新数据, 主动发送事件
                    self.sendActions(for: .valueChanged)
                })
                
            }
        }
    }
    
    //  记录当前滚动的视图
    var currentScrollView: UIScrollView?
    
    //  下拉箭头
    fileprivate lazy var pullDownImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //  风火轮
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    //  消息label
    fileprivate lazy var messageLabel: UILabel = {
        let label = UILabel()
        label.text = "下拉刷新"
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = UIColor.gray
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //  添加控件设置约束
    fileprivate func setupUI() {
        
        backgroundColor = UIColor.white
        
        //  添加子控件
        addSubview(pullDownImageView)
        addSubview(indicatorView)
        addSubview(messageLabel)
        
        //  使用原生代码完成自动布局
        pullDownImageView.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        //  添加约束
        addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: pullDownImageView, attribute: .centerX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: pullDownImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: indicatorView, attribute: .trailing, multiplier: 1, constant: 10))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        //  开启风火轮
        indicatorView.startAnimating()
    }
    
    //  将要添加到父视图上面会执行这个方法
    override func willMove(toSuperview newSuperview: UIView?) {
        
        //  判断父视图是否是UIScrollView的子类
        guard let scrollView = newSuperview as? UIScrollView else {
            return
        }
        
        //  设置大小
        self.frame.size = CGSize(width: scrollView.frame.size.width, height: ZZCRefreshControlHeight)
        //  修改y坐标
        self.frame.origin.y = -ZZCRefreshControlHeight
        
        //  引入kvo就是监听属性值的改变,使用当前对象监听属性值的改变就是kvo
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        //  记录滚动视图
        currentScrollView = scrollView
    }
    
    //  kvo监听方法,只要contentOffset这个发生改变就会回调这个方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        //  滚动的偏移量
        let contentOffSetY = currentScrollView!.contentOffset.y
        let limitY = -(currentScrollView!.contentInset.top + ZZCRefreshControlHeight)
        
        if currentScrollView!.isDragging {
            
            //  拖动情况下有normal状态进入pulling
            if contentOffSetY < limitY && refreshType == .normal {
                print("松手就刷新的状态")
                refreshType = .pulling
            } else if refreshType == .pulling && contentOffSetY >= limitY {
                print("下拉刷新")
                refreshType = .normal
            }
        } else {
            
            //  正在刷新 1. 松手. 2.刷新的状态必须pulling
            if refreshType == .pulling {
                print("正在刷新..")
                refreshType = .refreshing
            }
        }
        
        
    }
    
    //  结束刷新
    func endRefreshing() {
        //  状态重置
        refreshType = .normal
    }
    //  析构函数
    deinit {
        //  移除kvo
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }


    
    
}
